

/*
 * @Author: didididijiajiajia 11643763+didididijiajiajia@user.noreply.gitee.com
 * @Date: 2023-08-22 13:33:41
 * @LastEditors: didididijiajiajia 11643763+didididijiajiajia@user.noreply.gitee.com
 * @LastEditTime: 2023-08-26 13:07:40
 * @FilePath: \vue低代码101-111\low_code\src\utils\useblockDragger.js
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
import { reactive,computed } from "vue"
import { events } from "./event"
export function useBlockDragger(focusData, lastSelectBlock) {
    let dragState = {
        startX: 0,
        startY: 0,
        dragging: false
    }
    let markLine = reactive({
        x: null,
        y: null
    })

    //鼠标按下
    const mousedown = (e) => {
        const { width: Bwidth, height: Bheight } = lastSelectBlock.value
        dragState = {
            startX: e.clientX,
            startY: e.clientY,
            startLeft: lastSelectBlock.value.left,
            startTop: lastSelectBlock.value.top,//选中的最后一个元素拖拽前的位置
            dragging:false,
            startPosition: focusData.value.focus.map(({ top, left }) => ({ top, left })), //选中的位置
            lines: (() => {
                let lines = { x: [], y: [] }
                const { unfocus } = focusData.value
                unfocus.forEach(block => {
                    const { top: Atop, left: Aleft, width: Awidth, height: Aheight } = block
                    // 一个A物体和B物体有5x4种搭配关系 自动对合辅助线  //辅助线的位置,选中block的位置
                    lines.y.push({ showTop: Atop, top: Atop - Bheight })//顶对底
                    lines.y.push({ showTop: Atop, top: Atop })//顶对顶
                    lines.y.push({ showTop: Atop + Aheight / 2, top: Atop + Aheight / 2 - Bheight / 2 })//中对中
                    lines.y.push({ showTop: Atop + Aheight, top: Atop + Aheight - Bheight })//底对底
                    lines.y.push({ showTop: Atop + Aheight, top: Atop + Aheight })//底对顶

                    lines.x.push({ showleft: Aleft, left: Aleft - Bwidth })//左对右
                    lines.x.push({ showleft: Aleft, left: Aleft })//左对左
                    lines.x.push({ showleft: Aleft + Awidth / 2, left: Aleft + Awidth / 2 - Bwidth / 2 })//中对中
                    lines.x.push({ showleft: Aleft + Awidth, left: Aleft + Awidth - Bwidth })//右对右
                    lines.x.push({ showleft: Aleft + Awidth, left: Aleft + Awidth })//右对左
                })
                return lines
            })()
        }
        // 监听鼠标抬起,鼠标移动
        document.addEventListener('mouseup', mouseup)
        document.addEventListener('mousemove', mousemove)
    }
    const mouseup = (e) => {
        document.removeEventListener('mouseup', mouseup)
        document.removeEventListener('mousemove', mousemove)
        if(dragState.dragging){
            dragState.dragging = false, 
            events.emit("end")
        }
    }

    const mousemove = (e) => {
        let { clientX: moveX, clientY: moveY } = e //移动后的位置
        if(!dragState.dragging){
            dragState.dragging = true,
            events.emit("start") //触发事件记住拖拽前的位置
        }
        //计算最新的topleft,去lines找,找到显示线
        let left = moveX - dragState.startX + dragState.startLeft
        let top = moveY - dragState.startY + dragState.startTop
        
        let x=null;
        let y=null;
        for (let i = 0; i < dragState.lines.y.length; i++) {
            const { top: t, showTop: s } = dragState.lines.y[i] //获取每一根线
            if (Math.abs(t -top ) < 5) {   //如果两个线纵向距离小于5
                y = s; //将线的位置赋值给y
                moveY = dragState.startY - dragState.startTop + t //容器距离顶部的距离+目标的高度=最新的moveY
                break
            }
        }
        for (let i = 0; i < dragState.lines.x.length; i++) {
            const { left: l, showleft: sl } = dragState.lines.x[i] //获取每一根线
            if (Math.abs(l -left) < 5) {   //如果两个线纵向距离小于5
                x = sl; //将线的位置赋值给y
                moveX = dragState.startX - dragState.startLeft + l //容器距离顶部的距离+目标的高度=最新的moveY
                break
            }
        }
        markLine.x=x;
        markLine.y=y;
 
        let durX = moveX - dragState.startX
        let durY = moveY - dragState.startY
        focusData.value.focus.forEach((block, index) => {
            block.top = dragState.startPosition[index].top + durY
            block.left = dragState.startPosition[index].left + durX
        })
        
    }
    return { mousedown, markLine }
}